#pragma once

#include <stdint.h>
#include <memory>
#include <unordered_map>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>


class Request;
class Response;
class Channel;
class Handler
{
public:
    using Requests = std::unordered_map<uint64_t, std::shared_ptr<Request>>;
    using Responses = std::unordered_map<uint64_t, std::shared_ptr<Response>>;
    Handler();
    ~Handler();

    void request(const std::shared_ptr<Request> &req);
    void response(std::shared_ptr<Response> &&res);

    std::shared_ptr<Channel> channel() const;
    void setChannel(const std::shared_ptr<Channel> &channel);

private:
    void waitThreadFunc();

private:
    std::thread m_waitThread;
    Requests m_requests;
    Responses m_responses;
    std::mutex m_reqMutex;
    std::mutex m_resMutex;
    std::condition_variable m_emptyCond;
    std::atomic_bool m_running;
    std::shared_ptr<Channel> m_channel = nullptr;
};
